#include "muduo/net/TcpClient.h"
#include "muduo/net/EventLoopThread.h"
#include "muduo/net/TcpConnection.h"
#include "muduo/base/CountDownLatch.h"
#include <functional>
#include <iostream>
#include <string>
using namespace std;
using namespace placeholders;

class TranslateClient
{
public:
    TranslateClient(string s_ip, int s_port)
        : _clt(_loopthrad.startLoop(),
               muduo::net::InetAddress(s_ip, s_port), "TranslateServer"),
          _latch(1) // 只有大于0的时候调用wait才会阻塞
    {
        // 设置回调函数
        _clt.setConnectionCallback(std::bind(&TranslateClient::myconnect, this, _1));
        _clt.setMessageCallback(std::bind(&TranslateClient::mydeal, this, _1, _2, _3));
    }

    void connect()
    {
        _clt.connect(); // 异步操作
        _latch.wait();  // 建立连接成功被唤醒
    }

    bool send(const string &mess)
    {
        // 只有成功建立连接才能进行send
        if (_conn->connected())
        {
            _conn->send(mess);
            return true;
        }
        return false;
    }

private:
    // 连接成功建立的回调函数
    void myconnect(const muduo::net::TcpConnectionPtr &conn)
    {
        if (conn->connected())
        {
            _latch.countDown(); // 唤醒
            _conn = conn;
        }
        else
        {
            _conn.reset();
            cout << "连接关闭" << endl;
        }
    }
    // 收到响应后的回调处理函数
    void mydeal(const muduo::net::TcpConnectionPtr &conn, muduo::net::Buffer *buf,
                muduo::Timestamp)
    {
        cout << "收到数据: ";
        cout << buf->retrieveAllAsString() << endl;
    }

private:
    muduo::CountDownLatch _latch;           // 控制同步（请求连接是异步的）
    muduo::net::EventLoopThread _loopthrad; // 用于创建线程进行epoll事件关心
    muduo::net::TcpClient _clt;             // 用于回调事件就绪后的请求
    muduo::net::TcpConnectionPtr _conn;     // 用于数据请求发送
};

int main()
{
    TranslateClient clt("127.0.0.1", 8888);
    clt.connect(); // 建立连接

    while (true)
    {
        string buffer;
        getline(cin, buffer);
        bool ret = clt.send(buffer);
        if (ret == false)
        {
            cerr << "连接已经关闭" << endl;
            break;
        }
    }
    return 0;
}